import { AppDataSource, CrawlerTask, CrawledData } from '@weubi/shared';
import { Repository } from 'typeorm';
import { QueueService } from '../services/queue';

export class TaskController {
  private taskRepository: Repository<CrawlerTask>;
  private dataRepository: Repository<CrawledData>;
  private queueService: QueueService;

  constructor() {
    this.taskRepository = AppDataSource.getRepository(CrawlerTask);
    this.dataRepository = AppDataSource.getRepository(CrawledData);
    this.queueService = new QueueService();
  }

  // 获取任务列表
  async getTasks(query: any) {
    const {
      page = 1,
      limit = 20,
      status,
      engine,
      priority,
      search,
    } = query;

    const queryBuilder = this.taskRepository.createQueryBuilder('task');

    // 添加筛选条件
    if (status) {
      queryBuilder.andWhere('task.status = :status', { status });
    }

    if (engine) {
      queryBuilder.andWhere('task.engine = :engine', { engine });
    }

    if (priority) {
      queryBuilder.andWhere('task.priority = :priority', { priority });
    }

    if (search) {
      queryBuilder.andWhere(
        '(task.name ILIKE :search OR task.url ILIKE :search OR task.description ILIKE :search)',
        { search: `%${search}%` }
      );
    }

    // 分页和排序
    const offset = (page - 1) * limit;
    queryBuilder
      .orderBy('task.createdAt', 'DESC')
      .skip(offset)
      .take(limit);

    const [tasks, total] = await queryBuilder.getManyAndCount();

    return {
      success: true,
      data: tasks,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit),
      },
    };
  }

  // 创建任务
  async createTask(data: any): Promise<CrawlerTask> {
    const taskData = {
      ...data,
      config: data.config || {},
    };

    const task = this.taskRepository.create(taskData);
    const savedTask = await this.taskRepository.save(task);

    // 确保 savedTask 是单个对象而不是数组
    const singleTask = Array.isArray(savedTask) ? savedTask[0] : savedTask;

    // 如果有调度配置，设置定时任务
    if (singleTask.schedule) {
      await this.scheduleTask(singleTask);
    }

    return singleTask;
  }

  // 获取单个任务
  async getTaskById(id: string): Promise<CrawlerTask | null> {
    return await this.taskRepository.findOne({
      where: { id },
    });
  }

  // 更新任务
  async updateTask(id: string, data: any): Promise<CrawlerTask | null> {
    const task = await this.getTaskById(id);
    if (!task) return null;

    // 更新任务数据
    Object.assign(task, data);
    
    if (data.config) {
      task.config = { ...task.config, ...data.config };
    }

    const updatedTask = await this.taskRepository.save(task);

    // 如果调度配置发生变化，重新设置定时任务
    if (data.schedule !== undefined) {
      if (data.schedule) {
        await this.scheduleTask(updatedTask);
      } else {
        await this.unscheduleTask(updatedTask);
      }
    }

    return updatedTask;
  }

  // 删除任务
  async deleteTask(id: string): Promise<boolean> {
    const task = await this.getTaskById(id);
    if (!task) return false;

    // 取消调度
    if (task.schedule) {
      await this.unscheduleTask(task);
    }

    // 删除相关数据
    await this.dataRepository.delete({ taskId: id });
    
    // 删除任务
    await this.taskRepository.delete(id);

    return true;
  }

  // 执行任务
  async runTask(id: string): Promise<any> {
    const task = await this.getTaskById(id);
    if (!task) {
      throw new Error('Task not found');
    }

    if (!task.canRun) {
      throw new Error('Task cannot be run in current state');
    }

    // 添加到队列
    const job = await this.queueService.addCrawlerJob({
      taskId: task.id,
      url: task.url,
      engine: task.engine,
      config: task.config,
    });

    // 更新任务状态
    task.markAsRunning();
    await this.taskRepository.save(task);

    return {
      jobId: job.id,
      status: 'queued',
      message: 'Task added to queue successfully',
    };
  }

  // 暂停任务
  async pauseTask(id: string): Promise<CrawlerTask | null> {
    const task = await this.getTaskById(id);
    if (!task) return null;

    task.pause();
    return await this.taskRepository.save(task);
  }

  // 恢复任务
  async resumeTask(id: string): Promise<CrawlerTask | null> {
    const task = await this.getTaskById(id);
    if (!task) return null;

    task.resume();
    return await this.taskRepository.save(task);
  }

  // 取消任务
  async cancelTask(id: string): Promise<CrawlerTask | null> {
    const task = await this.getTaskById(id);
    if (!task) return null;

    task.cancel();
    
    // 取消调度
    if (task.schedule) {
      await this.unscheduleTask(task);
    }

    return await this.taskRepository.save(task);
  }

  // 获取任务统计
  async getTaskStats() {
    const stats = await this.taskRepository
      .createQueryBuilder('task')
      .select([
        'task.status as status',
        'task.engine as engine',
        'task.priority as priority',
        'COUNT(*) as count',
      ])
      .groupBy('task.status, task.engine, task.priority')
      .getRawMany();

    // 处理统计数据
    const statusStats: Record<string, number> = {};
    const engineStats: Record<string, number> = {};
    const priorityStats: Record<string, number> = {};

    stats.forEach(stat => {
      const count = parseInt(stat.count);
      
      statusStats[stat.status] = (statusStats[stat.status] || 0) + count;
      engineStats[stat.engine] = (engineStats[stat.engine] || 0) + count;
      priorityStats[stat.priority] = (priorityStats[stat.priority] || 0) + count;
    });

    const totalTasks = await this.taskRepository.count();
    const activeTasks = await this.taskRepository.count({
      where: { isActive: true },
    });

    return {
      total: totalTasks,
      active: activeTasks,
      byStatus: statusStats,
      byEngine: engineStats,
      byPriority: priorityStats,
    };
  }

  // 设置定时任务
  private async scheduleTask(task: CrawlerTask): Promise<void> {
    // 这里应该使用 cron 库来设置定时任务
    // 暂时简单处理
    console.log(`Scheduling task ${task.id} with cron: ${task.schedule}`);
  }

  // 取消定时任务
  private async unscheduleTask(task: CrawlerTask): Promise<void> {
    console.log(`Unscheduling task ${task.id}`);
  }
}
